using Cinemachine;
using Framework.Timer;
using UnityEngine;

namespace System.Game
{
    [RequireComponent(typeof(CinemachineVirtualCamera))]
    public class CameraNode : ChooseEntity
    {

        public CameraType CameraType;

        private CinemachineVirtualCamera _virtualCamera;
        public  CinemachineVirtualCamera VirtualCamera => this._virtualCamera;

        private CinemachineBasicMultiChannelPerlin _basicMultiChannelPerlin;

        private TimeHandler _timeHandler;
        

        protected override void OnInit()
        {
            this._virtualCamera           = this.GetComponent<CinemachineVirtualCamera>();
            this._basicMultiChannelPerlin = this._virtualCamera.GetCinemachineComponent<CinemachineBasicMultiChannelPerlin>();
            if (this._basicMultiChannelPerlin == null)
            {
                this._basicMultiChannelPerlin = this._virtualCamera.AddCinemachineComponent<CinemachineBasicMultiChannelPerlin>();
            }
            this._basicMultiChannelPerlin.m_NoiseProfile = UnityEngine.Resources.Load<NoiseSettings>("Config/Shake");
            this._basicMultiChannelPerlin.m_FrequencyGain = 0.85f;
            this.UpdateShake(0);
        }

        protected override void OnChangeState(bool isOn)
        {
            this._virtualCamera.Priority = isOn ? 20 : 10;
            base.OnChangeState(isOn);
        }

        public void SetShake(float inTime = 0, float time = 0, float outTime = 0, float scale = 0)
        {
            this._timeHandler?.Kill();
            this._timeHandler = GameUpdateMgr.Instance.CreateTimer(inTime ,
                                                                   () =>
                                                                   {
                                                                       this.UpdateShake(scale);
                                                                       this._timeHandler = GameUpdateMgr.Instance.CreateTimer(time ,
                                                                                                                              () =>
                                                                                                                              {
                                                                                                                                  this._timeHandler = GameUpdateMgr.Instance.CreateTimer(outTime , () => { this.UpdateShake(0); } ,
                                                                                                                                                                                         f =>
                                                                                                                                                                                         {
                                                                                                                                                                                             this.UpdateShake((1 - f) * scale); 
                                                                                                                                                                                         });
                                                                                                                              });
                                                                   } , f => { this.UpdateShake(scale * f); });
        }

        private void UpdateShake(float scale)
        {
            this._basicMultiChannelPerlin.m_AmplitudeGain = scale;
        }

    }
}